#ifndef QUIRREL_BASE_HPP
#define QUIRREL_BASE_HPP

#include "squirrel.h"

#define SQ_CHECK_R(cond, msg, vm, ret) \
    do { \
        if (!SQ_SUCCEEDED(cond)) { \
            fprintf(stderr, "SQUIRREL CHECK ERROR: " msg "\n"); \
            sq_getlasterror(vm); \
            const SQChar *error = nullptr; \
            sq_getstring(vm, -1, &error); \
            fprintf(stderr, "SQUIRREL VM Error: %s\n", error); \
            return (ret); \
        } \
    } while(false)\

#define SQ_CHECK_RV(cond, msg, vm) \
    do { \
        if (!SQ_SUCCEEDED(cond)) { \
            fprintf(stderr, "SQUIRREL CHECK ERROR: " msg "\n"); \
            sq_getlasterror(vm); \
            const SQChar *error = nullptr; \
            sq_getstring(vm, -1, &error); \
            fprintf(stderr, "SQUIRREL VM Error: %s\n", error); \
            return; \
        } \
    } while(false)\

struct VMHelper {
    HSQUIRRELVM vm;
    inline operator HSQUIRRELVM () const
    {
        return vm;
    }
    static VMHelper &GetVMInstance();
private:
    VMHelper ();
    ~VMHelper ();
    VMHelper (const VMHelper &)            = delete;
    VMHelper (VMHelper &&)                 = delete;
    VMHelper &operator= (const VMHelper &) = delete;
    VMHelper &operator= (VMHelper &&)      = delete;

    static void compile_error_handler(HSQUIRRELVM, const SQChar* desc, const SQChar* source, SQInteger line, SQInteger column);
    static void printfunc(HSQUIRRELVM v, const SQChar* s, ...);
    static void errorfunc(HSQUIRRELVM v, const SQChar* s, ...);
};

#endif /* QUIRREL_BASE_HPP */
